package net.asfun.jvalog.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.jdo.Query;

import com.google.appengine.api.datastore.Text;

import net.asfun.jvalog.except.InteractException;
import net.asfun.jvalog.po.Paper;
import net.asfun.jvalog.service.Jdoer;
import net.asfun.jvalog.service.JdoerFactory;
import net.asfun.jvalog.task.UpdateManager;
import net.asfun.jvalog.view.PagerInfo;
import net.asfun.jvalog.view.SiteInfo;

public class Page {

	private Paper paper;
	
	public Page() {
		paper = new Paper();
		paper.setType(1);
	}
	
	private Page(Paper apage){
		if ( apage == null ) {
			throw new InteractException("Page not found");
		}
		paper = apage;
	}
	
	public static List<Page> listPublished() {
		List<Page> list = new ArrayList<Page>();
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		Query query = dbp.prepareQuery();
		query.setFilter("type == 1 && published == true");
		Collection<Paper> res = dbp.more(query);
		for(Paper paper : res) {
			list.add(new Page(paper));
		}
		return list;
	}
	
	public static List<Page> list(PagerInfo pager) {
		List<Page> list = new ArrayList<Page>();
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		pager.setTotal(dbp.all().size());
		Query query = dbp.prepareQuery();
		query.setFilter("type == 1");
		query.setOrdering("published ascending, date descending");
		query.setRange(pager.getStart(), pager.getEnd());
		Collection<Paper> res = dbp.more(query);
		for(Paper paper : res) {
			list.add(new Page(paper));
		}
		return list;
	}
	
	public static Page load(Long id) {
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		return new Page(dbp.load(id));
	}
	
	public static Page load(String uri) {
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		Query q = dbp.prepareQuery();
		q.setFilter("uri == link && published == true");
		q.declareParameters("String link");
		return new Page(dbp.unique(q, uri));
	}
	
	public static void remove(Long id) {
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		Paper paper = dbp.load(id);
		if ( paper != null ) {
			if ( paper.isPublished() ) {
				UpdateManager.enableStaticTask();
			}
			Unifier.unsetUnique(paper.getKey(), "slogan");
			dbp.delete(paper);
		}
	}
	
	private void generateURI() {
		paper.setUri("page/" + paper.getSlogan());
	}
	
	public void update() {
		//make sure slogan unique
		if ( ! Unifier.isUnique(paper.getKey(), "slogan", paper.getSlogan()) ) {
			paper.setSlogan(paper.getSlogan() + "~1");
			this.update();
			return;
		}
		Unifier.setUnique(paper.getKey(), "slogan", paper.getSlogan());
		generateURI();
		if ( paper.isPublished() ) {
			UpdateManager.enableStaticTask();
		}
	}
	
	public void save() {
		//make sure slogan unique
		if ( ! Unifier.isUnique("Paper", "slogan", paper.getSlogan()) ) {
			paper.setSlogan(paper.getSlogan() + "~1");
			this.save();
			return;
		}
		generateURI();
		Jdoer<Paper> dbp = JdoerFactory.getPaperJdo();
		dbp.save(paper);
		Unifier.setUnique(paper.getKey(), "slogan", paper.getSlogan());
		if ( paper.isPublished() ) {
			UpdateManager.enableStaticTask();
		}
	}
	
	public void setPublished(boolean b) {
		paper.setPublished(b);
	}
	
	public boolean isPublished() {
		return paper.isPublished();
	}
	
	public void setArticle(String article) {
		paper.setContent(new Text(article));
	}
	
	public String getArticle() {
		return paper.getContent().getValue();
	}

	public void setDate(Date date) {
		paper.setDate(date);
	}
	
	public Date getDate() {
		return paper.getDate();
	}
	
	public Long getId() {
		return paper.getKey().getId();
	}
	
	public String getLink() {
		return SiteInfo.getInstance().getUrl() + paper.getUri() + ".html";
	}
	
	public void setTitle(String title) {
		paper.setTitle(title);
	}
	
	public String getTitle() {
		return paper.getTitle();
	}

	public void setSlogan(String slogan) {
		paper.setSlogan(slogan);
	}
	
	public String getSlogan() {
		return paper.getSlogan();
	}

	public void setExcerpt(String excerpt) {
		paper.setExcerpt(excerpt);
	}
	
	public String getExcerpt() {
		return paper.getExcerpt();
	}
}
